import getopt
import sys
# 闭包
# 优点: 不定义全局变量, 也可以让一个函数持续访问(和修改)一个外部变量
#      闭包函数引用的外部变量是外部函数的内部变量, 作用域封闭, 难以被误修改
# 缺点: 额外的内存占用(影响比较小)


def outer(outer_val):
    def inner(inner_val):
        val = outer_val + inner_val  # 内部函数使用外部函数的变量
        print(val)

    return inner  # 返回内部函数形成闭包


def set_money(money=0):
    def opr(count, is_get_money=False):
        nonlocal money  # 想要修改money的值, 需要提前使用nonlocal声明
        if is_get_money:
            money -= count
            print(f'get money:{count}, money={money}')
        else:
            money += count
            print(f'save money:{count}, money={money}')

    return opr


# 装饰器
# 本质上是用的闭包调用, 可以用语法糖写法
# 先创建一个闭包函数, 在闭包函数内部调用目标函数
# 可以达到不改动目标函数的同时, 增加额外的功能
def ot(fc):
    total = 4

    def ir(name, age, score):
        nonlocal total
        print('增加了一点内容')
        fc(name, age)
        total += score
        print(f'又增加了一点内容, total = {total}')

    return ir


@ot
def say_something(name, age):
    print(f'啊哈哈哈, {name}{age}岁了')


# 命令行参数
def get_opts():
    # 带:或=的要传入参数才行
    opts, args = getopt.getopt(sys.argv[1:], "u:p", ["help", "login="])
    print(opts, args)
    # python py_stage_3/py_advance_tips.py -u User -p --help --login ok
    # [('-u', 'User'), ('-p', ''), ('--help', ''), ('--login', 'ok')] []


if __name__ == '__main__':
    # func = outer('函数内的"全局变量"')
    # func('内部自己使用的变量111')
    # func('内部自己使用的变量222')
    #
    # money1 = set_money()
    # money1(100)
    # money1(100)
    # money1(300, is_get_money=True)
    # money2 = set_money(10)
    # money2(200)
    # money2(100, is_get_money=True)

    # say_something('张三', 9, 93)
    get_opts()
